package com.doubao.wechat.service.impl;

import com.doubao.common.result.Result;
import com.doubao.wechat.entity.PaymentOrder;
import com.doubao.wechat.entity.RefundOrder;
import com.doubao.wechat.mapper.PaymentOrderMapper;
import com.doubao.wechat.mapper.RefundOrderMapper;
import com.doubao.wechat.service.PaymentNotificationService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 支付通知处理服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PaymentNotificationServiceImpl implements PaymentNotificationService {

    private final PaymentOrderMapper paymentOrderMapper;
    private final RefundOrderMapper refundOrderMapper;
    private final ObjectMapper objectMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> handlePaymentSuccessNotification(Map<String, Object> notificationData) {
        try {
            // 解析通知数据
            String outTradeNo = (String) notificationData.get("out_trade_no");
            String transactionId = (String) notificationData.get("transaction_id");
            String tradeState = (String) notificationData.get("trade_state");

            log.info("处理支付成功通知：商户订单号={}, 微信支付单号={}, 交易状态={}", outTradeNo, transactionId, tradeState);

            // 查询本地订单
            PaymentOrder paymentOrder = paymentOrderMapper.selectByOutTradeNo(outTradeNo);
            if (paymentOrder == null) {
                log.error("未找到对应的订单记录：{}", outTradeNo);
                return Result.failed("未找到对应的订单记录");
            }

            // 判断订单状态
            if ("SUCCESS".equals(paymentOrder.getStatus())) {
                log.info("订单已处理，无需重复处理：{}", outTradeNo);
                return Result.success();
            }

            // 更新订单状态
            if ("SUCCESS".equals(tradeState)) {
                paymentOrder.setStatus("SUCCESS");
                paymentOrder.setTradeNo(transactionId);
                paymentOrder.setPayTime(LocalDateTime.now());
                paymentOrder.setUpdatedAt(LocalDateTime.now());
                paymentOrderMapper.updateById(paymentOrder);

                // TODO: 发送支付成功消息到消息队列，用于后续处理
                // 例如：更新会员状态、分配商品权益等

                log.info("订单支付成功处理完成：{}", outTradeNo);
                return Result.success();
            } else {
                log.warn("订单支付状态异常：{}, {}", outTradeNo, tradeState);
                return Result.failed("订单支付状态异常");
            }
        } catch (Exception e) {
            log.error("处理支付成功通知异常", e);
            return Result.failed("处理支付通知异常：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> handleRefundSuccessNotification(Map<String, Object> notificationData) {
        try {
            // 解析通知数据
            String outTradeNo = (String) notificationData.get("out_trade_no");
            String outRefundNo = (String) notificationData.get("out_refund_no");
            String refundId = (String) notificationData.get("refund_id");
            String refundStatus = (String) notificationData.get("refund_status");
            Integer refundAmount = (Integer) notificationData.get("refund_amount");

            log.info("处理退款成功通知：商户订单号={}, 商户退款单号={}, 微信退款单号={}, 退款状态={}, 退款金额={}",
                    outTradeNo, outRefundNo, refundId, refundStatus, refundAmount);

            // 查询本地退款单
            RefundOrder refundOrder = refundOrderMapper.selectByOutRefundNo(outRefundNo);
            if (refundOrder == null) {
                log.error("未找到对应的退款记录：{}", outRefundNo);
                return Result.failed("未找到对应的退款记录");
            }

            // 判断退款状态
            if ("SUCCESS".equals(refundOrder.getStatus())) {
                log.info("退款已处理，无需重复处理：{}", outRefundNo);
                return Result.success();
            }

            // 更新退款状态
            if ("SUCCESS".equals(refundStatus)) {
                // 1. 更新退款单状态
                refundOrder.setStatus("SUCCESS");
                refundOrder.setRefundId(refundId);
                refundOrder.setRefundTime(LocalDateTime.now());
                refundOrder.setUpdatedAt(LocalDateTime.now());
                // 保存通知数据
                try {
                    refundOrder.setNotifyData(objectMapper.writeValueAsString(notificationData));
                } catch (Exception e) {
                    log.warn("保存退款通知数据失败", e);
                }
                refundOrderMapper.updateById(refundOrder);

                // 2. 更新支付订单的退款状态
                PaymentOrder paymentOrder = paymentOrderMapper.selectByOutTradeNo(outTradeNo);
                if (paymentOrder != null) {
                    // 计算退款后的状态
                    Integer currentRefundAmount = paymentOrder.getRefundAmount();
                    // 确保退款金额已正确计入
                    if (currentRefundAmount < refundOrder.getRefundAmount()) {
                        paymentOrder.setRefundAmount(currentRefundAmount + refundOrder.getRefundAmount());
                        
                        // 判断是否全额退款
                        if (paymentOrder.getRefundAmount() >= paymentOrder.getAmount()) {
                            paymentOrder.setRefundStatus(2); // 全额退款
                            paymentOrder.setStatus("REFUNDED");
                        } else {
                            paymentOrder.setRefundStatus(1); // 部分退款
                        }
                        
                        paymentOrder.setUpdatedAt(LocalDateTime.now());
                        paymentOrderMapper.updateById(paymentOrder);
                        log.info("更新支付订单退款状态成功：订单号={}, 退款状态={}, 退款金额={}/{}", 
                                outTradeNo, paymentOrder.getRefundStatus(), paymentOrder.getRefundAmount(), paymentOrder.getAmount());
                    }
                } else {
                    log.warn("未找到对应的支付订单：{}", outTradeNo);
                }

                // TODO: 发送退款成功消息到消息队列，用于后续处理
                // 例如：通知用户退款成功、更新相关业务状态等

                log.info("退款成功处理完成：{}", outRefundNo);
                return Result.success();
            } else {
                log.warn("退款状态异常：{}, {}", outRefundNo, refundStatus);
                return Result.failed("退款状态异常");
            }
        } catch (Exception e) {
            log.error("处理退款成功通知异常", e);
            return Result.failed("处理退款通知异常：" + e.getMessage());
        }
    }
}